import { Inject, Provide } from '@midwayjs/decorator';
import {
  BaseService,
  CoolEventManager,
  CoolCommException,
} from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/orm';
import { UserInfoEntity } from '../entity/info';
import { UserRelationEntity } from '../entity/userRelation';
import { Utils } from '../../../comm/utils';
import { UserWechatService } from './wechat';
import { getManager, Repository, Brackets } from 'typeorm';

/**
 * 用户
 */
@Provide()
export class UserInfoService extends BaseService {
  @InjectEntityModel(UserInfoEntity)
  userInfoEntity: Repository<UserInfoEntity>;

  @Inject()
  userWechatService: UserWechatService;

  @InjectEntityModel(UserRelationEntity)
  userRelationEntity: Repository<UserRelationEntity>;

  @Inject('cool:coolEventManager')
  coolEventManager: CoolEventManager;
 
  @Inject()
  utils: Utils;
  /**
   * 绑定socketId
   * @param socketId
   * @param userId
   */
  async bindSocketId(socketId, userId) {
    await this.userInfoEntity
      .createQueryBuilder()
      .update()
      .set({ socketId })
      .where('id =:userId', { userId })
      .execute();
  }

  /**
   * 个人信息
   */
  async personal(userId) {
    return await this.userInfoEntity.findOne({ id: userId });
  }

  /**
   * 修改之后
   * @param params
   */
  async modifyAfter(params) {
    if (params.id) {
      this.coolEventManager.emit('updateUser', params, 1);
    }
  }

  /**
   * 绑定手机
   * @param code
   * @param encryptedData
   * @param iv
   * @param userId
   */
  async bindMiniPhone(code, encryptedData, iv, userId) {
    const phoneInfo = await this.userWechatService.miniPhone(
      code,
      encryptedData,
      iv
    );
    const user = await this.userInfoEntity.findOne({
      phone: phoneInfo['phoneNumber'],
    });
    if (user) {
      throw new CoolCommException('该手机号已被绑定');
    }
    await this.userInfoEntity
      .createQueryBuilder()
      .update()
      .set({ phone: phoneInfo['phoneNumber'] })
      .where('id=:id', { id: userId })
      .execute();
    return phoneInfo['phoneNumber'];
  }

  /**
   * 批量查用户
   * @param ids [number]
   */
  async transformInUser(arr: [any], field = 'userId') {
    if (Array.isArray(arr) && arr.length > 0) {
      const ids = [];
      arr.map(v => {
        if (v[field]) {
          ids.push(v[field]);
        }
      });

      const set = new Set(ids); //去重复
      const userList = await this.userInfoEntity
        .createQueryBuilder('a')
        .select('a.id,a.headimgurl,a.cover,a.nickname,a.sn,a.source,a.status,a.motto,a.count_follows,a.count_collects,a.count_teams,a.count_loves')
        .where('a.id in (:ids)', { ids: [...set] })
        .getRawMany();

      arr.map((v, k) => {
        userList.map(u => {
          if (v[field] == u.id) {
            arr[k]['user'] = u;
          }
        });
      });
    }
    return arr;
  }
  /**
   * 批量查用户
   * @param arr 数组
   * @param field 要获取的key
   * @param order 排序规则 
   * @returns 数组
   */
  async findUserByIds(arr:any[], field = 'userId',order:string='count_loves') {
    if (Array.isArray(arr) && arr.length > 0) {
      const ids = [];
      arr.map(v => {
        if (v[field]) {
          ids.push(v[field]);
        }
      });
      const set = new Set(ids); //去重复
      const userList = await this.userInfoEntity
        .createQueryBuilder('a')
        .select("a.id,a.headimgurl,a.cover,a.nickname,a.sn,a.source,a.status,a.motto,a.count_follows,a.count_collects,a.count_teams,a.count_loves")
        .where('a.id in (:ids)', { ids: [...set] })
        .orderBy(order)
        .getRawMany();
      return userList;

    } else {
      return []
    }
  }

  async info(id: any, infoIgnoreProperty?: string[]): Promise<any> {
    const model = this.userInfoEntity
      .createQueryBuilder('a')
      .select('a.id,a.headimgurl,a.cover,a.nickname,a.sn,a.source,a.status,a.motto,a.count_follows,a.count_collects,a.count_teams,a.count_loves')
      .where('a.id in (:id)', { id });
    const info = await model.getRawOne();
    return this.utils.ignoreProperty(info, infoIgnoreProperty);
  }

  async getBySn(sn: any, infoIgnoreProperty?: string[]): Promise<any> {
    const model = this.userInfoEntity
      .createQueryBuilder('a')
      .select('a.id,a.headimgurl,a.cover,a.nickname,a.sn,a.source,a.status,a.motto,a.count_follows,a.count_collects,a.count_teams,a.count_loves')
      .where('a.sn in (:sn)', { sn });
    const info = await model.getRawOne();
    return this.utils.ignoreProperty(info, infoIgnoreProperty);
  }

  async getSn(sn: string) {
    return await this.userInfoEntity
      .createQueryBuilder()
      .where('sn = :sn', { sn })
      .getOne();
  }

  /**
   * 嗦粉处理 绑定用户上下级关系
   */
  async setUserRelation(sn: string, newUser: any) {
    await getManager().transaction(async manager => {
      if (!sn) return;
      const parentUser = await this.getSn(sn);

      //补充用户关系
      if (newUser.id > 0 && sn && parentUser.id) {
        console.log('补充用户关系');
        // 邀请链
        let userPath = [];
        const userSql = `SELECT @r AS _id,( SELECT @r := parent_id FROM user_relation WHERE user_id = _id ) AS parent_id,@l := @l + 1 AS lvl 
        FROM ( SELECT @r := ${parentUser.id}, @l := 0 ) vars,user_relation AS m WHERE @r <> 0 order by lvl desc`;
        const resultUserParent = await this.nativeQuery(userSql);
        if (resultUserParent.length) {
          userPath = [
            ...new Set(
              resultUserParent
                .filter(v => !(v._id == parentUser.id && !v.parent_id))
                .map(v => v._id)
            ),
          ];
          if (!userPath.length) {
            userPath.push(parentUser.id);
          }
        }
        userPath.push(newUser.id);
        const userRelation = new UserRelationEntity();
        userRelation.parentId = parentUser.id;
        userRelation.userId = newUser.id;
        userRelation.path = userPath.join(',');
        await manager.save(UserRelationEntity, userRelation);
      }
    });
  }

  /**
   * 设计师热度最高的
   * @param query 
   * @returns list
   */

  async findhotRank(query: any): Promise<any> {
    let { order = "id", page = 1, size = 15, sort = 'DESC', } = query
    // 热度最高的 SUM(count_loves+count_teams+count_follows+count_collects)

    // 设计新星的  最近发帖 点赞最高的 

    return await this.userInfoEntity.createQueryBuilder()
      .select("*")
      .addSelect('SUM(count_loves+count_teams+count_follows+count_collects)', 'ranking')
      .where(
        new Brackets(qb => {
          qb.where('1 = 1');
        })
      )
      .groupBy(order)
      .orderBy('ranking', sort == 'DESC' ? 'DESC' : 'ASC')
      .offset(size * (page - 1))
      .limit(size)
      .getRawMany();


  }
}
